Last lecture.
We started off on our speed simulator game.
We generated a nice big open map for player to be able to, well, run around in, and we've got some
borders as well, just to make sure they don't fall off the end of the map.
So in today's lesson we are going to start work on the walking system.
So this is like the base part of our game really.
When the player walks forward a bit their speed increases.
Now before we can calculate things like when is a player walking forward and to give them more speed,
we first need to set up Leaderstats and obviously data stores because we need a speed value that the
player has now.
If quickly play the game.
The speed value is already in the humanoid.
Um, in the humanoid and walk speed here.
It already is here.
However, um, it would be better to put it, um, using leader stats and added value in called speed.
The reason why I've opted to do this is, well, it displays on the leaderboard to start off with,
and it is easier to access than in the humanoid.
So I've chosen to do that and it easier to save and stuff as well.
So I just thought it would be easier method to use here.
So we're going to add a sub a standard script into server script service.
I'm going to call this leader stats.
So is it going to be setting up all the values and things like that?
So this is where also our data store is going to go.
So we will first need to fetch data store service.
So local data store service is equal to game.
Come on get service.
Data store service.
Now I think when I mentioned with Leaderstats and with data stores that you're going to be doing it
for every game, you pretty much are.
If a game has any kind of currency or anything similar to currency, you're probably going to be using
a data stores and using Leaderstats.
So this is a very common script here to write.
Um, we're going to reference our data store.
Is equal to and.
Datastore.
Service.
Colon.
Get.
Datastore.
I'm going to call it datastore and give it.
You don't need to give it any fancy name.
Okay.
It's going.
Then get to the players.
Go!
Players is equal to game.
Get service players.
Okay.
Perfect.
So we want to do our first bit, which is when the player is added.
So players dot player.
Added connect function player.
So when the play is added, we first want to add in all of these values.
So we will first want to add in our leader stats.
So local leader stats is equal to instance dot new folder.
Into, um.
Into the player.
Leaderstats dot name here.
Remember it leads to lowercase l.
Very common mistake.
People make their leaderstats like that.
They're in this leaderstats I'm going to add in firstly the speed.
So local speed is equal to instance dot new.
Now we can even write an integer value or a number value.
I'm going to opt in to use a number value.
Now the reason for this is because, um, well, the speed is going to be based on the walk speed.
Now, to increase your speed from 0 to 1 or 1 to 2 is quite a big jump.
Um, when we create items and stuff, they have to have very large cooldowns.
So I want you to be able to walk forward and just gain a little bit of speed.
Really.
Um, so a number value would allow you to put in decimals in your number.
Okay.
These are going to go into leaderstats.
Um speed dot name is equal to speed like that there, and the starting speed value is going to be equal
to zero.
Now this will mean that for a short bit of time, um, you won't be able to move because there'll be
no way to increase your speed.
Um, however, once we do look at the walking system, this will be.
This will fix itself here.
And I'm also going to add a level, um, value into leaderstats.
This is going to we're going to.
Yeah.
Because this is going to be to do with our experience and leveling system that we're going to add,
um, a bit later on.
So I'm going to add a um variable called level, which is going to, which is basically going to store
the level of account the player is currently on.
So instance dot new.
This will be just an integer value.
Into leaders.
That's.
Level.
Then dot name is equal to level.
Can't type.
Um, level dot value is going to be equal to one to start off with.
Now this is usually where we leave it.
However, there is one other thing I want to store which is the experience.
Now you have different levels and based on how much experience the player has like exp, the things
that players can pick up or get it from doing certain tasks and stuff like that, it will then put them
more along the way to um, that their next level.
Now we can't really store the experience on the leaderboard just because I think it looks a bit clunky.
I mean, the level in the experience both show the same thing, and um, it's not something that's typically
shown on the leaderboard.
So we want it to be saved but not to be shown on the leaderboard.
So we're going to add in a another folder into the player called something different and then store
our value in there instead of storing it inside Leaderstats.
Now I use this quite commonly for a lot of my games, which is making a folder called player values.
This contains values such as like all their experience.
Um, do we have this game pass active?
Um, stuff like that, which you wouldn't necessarily want to show on the leaderboard, but I use very
commonly and are very important.
Um.
We're gonna add in a folder here into the player player values.
Dot name is equal to player values.
Do be careful spelling all these as if you do spell them wrong here.
It will be difficult when you reference them later on.
I'm going to add in a experience value which will hold the total amount experience that the player has.
Experience is equal to instance dot new x, y and experience.
Add in an integer value here into player values.
Experience dot name is equal to experience and then experience dot value is going to be start off.
Default is zero.
Cool.
Lots of stuff adding in.
Then we've got it all there already.
And we're going to add have a go now at saving our data.
So the bits we want to save is the speed.
So speed data is going to start off as nil.
Now we could save a level.
However um it's more important to store the save experience rather than the level because given the
experience you can very easily calculate the level.
However, given the level, you can't calculate how much experience a player has when the player gets
up to high levels which take which take more experience in order to level up.
You don't want the experience to reset every single time.
So the experience is actually more important to save rather than the level.
So we're not going to be saving the level because we can calculate that ourselves when the player joins.
So experience data is equal to nil there okay.
So let's do our success message pickle.
Success comma error message is equal to call function.
And we're going to be setting here speed data to be equal to the data store and data store.
Colon get a sink and we are.
The key here is the players user ID with a tag here of speed.
And we can just copy and paste this line down here, which will be something similar but for experience
data.
Experience data and call this experience.
Cool.
From there.
If it is a success success, then we want to say that the speeds value in the Leaderstats is equal to
the speed data and the experience value.
Is equal to the experienced data.
And just to make sure if if it's not a success and there is any issues, we just want to warn that error
message so we can see what went wrong.
Cool.
That's everything on the player added side.
Now we just need to do a player leaving side which is not too much more difficult.
Player moving colon connect function and the player parameter that is leaving.
And we're going to create another success error message.
Call success.
Common error message is equal to Pcall.
Function.
And here we are wanting to get async with the data store to save our data.
So get async with the players player dot user id.
Um.
Dot dot.
And speed.
And I'm going to repeat that again, but for experience.
Like that for.
Okay.
Perfect.
Um.
So we are thinking that back up afterwards.
Um, and of course, yeah, if it doesn't work, if not success.
We just want to warn.
I've noticed I've put weight above there on line 38.
That needs to be a warn.
Warn?
The error message.
You can't wait.
An error message?
Okay, perfect.
Now we will just need to go into game settings here to change.
Um, security enables you to access API service if it needs to be on so the studio can have access to
data stores.
Now, let's just play the game and leave the game just to make sure that all this is working properly
before we continue.
Um, so we've got the speed and the level.
Perfect.
And if we look in the player, we've got the player values here, the experience and the leader stats
here as well.
And if when we leave the game, um.
No errors are outputted there, so we know we've done it all.
Good.
Okay, cool.
Let's move on then to the walking system.
Let's add another script into the script service.
And let's call this, um, walking.
System.
Now, we haven't really talked too much about organization of scripts because in our game there is all
already organized as such.
Um, and when we're talking about it in lectures, it's kind of just individual topics.
But with a game you do want to make sure everything's nice and organized as well.
Now, um, I could very easily put, um, some of these scripts that I make inside of each other.
For example, this is using another player added event.
I could very easily add it into Leaderstats, but it's just for sake of organization because this isn't
really relevant to leaderstats or events using the values.
There's some kind of calculations involved and stuff like that.
So by adding it into Leaderstats, if there's an issue with that script, it makes it more it makes
it more difficult to fix it.
So it's it's more difficult to maintain if you just have 1 or 2 very long scripts.
So it's a very good idea to block out your code in different scripts.
Okay.
So there's a bit of walking system.
So we need to get that player added function event.
Sorry.
So players is equal to game get service players and then players dot player added connect function player.
Okay.
Um, so we then want to get the character as this is going to be all to do with the, um, character
and the humanoids walk speed.
We need to determine when the player is moving and if they are moving, then increase their speed.
Now this can be done using a.
Um, property inside of the humanoid called Move Direction, which is basically going to save us here
from doing a lot of difficult code.
Um, where is it?
Somewhere here.
Move direction.
It'll probably be grayed out.
Move direction here.
Okay, so if we're not if we're not moving, it's 000.
But if I move, it's not 000.
It's something else basically.
And that's that's the issue here.
That's what um, we're going to be using.
Not an issue.
What we're going to be using.
So we're going to we're going to check is it 000.
If it is that means.
Using um order to determine this.
So let's go ahead and reference the character.
So local character is equal to player dot character.
And I've also seen it referenced this way.
So saying it's equal to player character or player dot character colon.
Um so player.
Dot character added colon weight, which is quite cool actually.
So if it's not that, it will then do that which I quite like.
Um, so we're going to try that out.
We're going to reference the humanoid.
So local humanoid is equal to character colon weight for child humanoid.
And then we're going to make a value here called weight.
Do it down here basically called local is moving is equal to false.
Now this here is something you probably haven't seen too much.
But um, this is just to do with the logic really.
Um, so sometimes we make boolean values variables and we're not actually we're not we don't use them
to change properties or things like that, but we just use it to check it.
So something influences this, this variable here.
And then later on we check that variable.
This is a really good way to structure our code and to make things a lot, a lot less messy basically.
Okay.
Um, now we're going to set the starting speed of the humanoid to be zero.
So humanoid walk speed.
It's not autocompleting, but that should be okay.
So.
But that is the starting speed.
Good idea to just note that because that's that's quite an important value.
So the player won't be able to move at all to start off with.
So we need to determine when this move direction value changes.
And this will will we can use the dot change value event for this.
Because this will run when any property of the humanoid changes.
So humanoid dot changed colon connect function with the property.
Now it's very important here to check um, do the properties move direction?
So if property is equal to move direction because there's lots of properties in the humanoid that could
be changing.
So if the properties is if the properties move direction, we know that has been changed.
Okay.
So there's two possibilities here.
Either the move direction is vector three new 000.
So it is the player isn't moving or if it's any other value they have to be currently moving.
So we could say if humanoid.
Dot move direction.
Is equal equal vector 3.1 remembers a little shortcut we learned much quicker than writing out vector
three point new 000, and also prevents us changing stuff as well.
So not sorry, not not .1.0.
Okay, so if it's zero they are not moving.
So is moving is equal to false.
And see how we can easily it's it's easier to read because we can see okay if this occurs is moving
is false.
So the plate isn't moving.
Whereas if we were to just put some code in here straight away, it a bit difficult to see what actually
is going on here.
Then, if it is any other value is moving is equal to true.
Okay, perfect.
Um, so outside of the changed value here, um.
Hmm.
No, I have done.
Yeah.
So I had a thought for a minute that we could put it inside here.
Um, but I'll explain why we can't in a minute.
Okay, so after that, we have to come outside of this change because, um, what I was saying here
is we don't just want to.
So this is the bit now we're going to be updating the updating the speed.
If they are moving now, we can't put this in the change because otherwise why.
Because in this case it wouldn't be.
It would be changed.
And if it just moving forward, none of their properties would be changing.
So, um, we do need to put it down here.
So we're going to make we're going to fetch some values we will need, um, the leader stats.
So local um leader stats.
Is equal to player column weight for child, lowercase l for leaderstats, and then local not player
values.
Local speed is equal to player column weight for child.
Uh, no leader starts on speed, so.
Okay.
Perfect.
So this is then the this is when asked um doing the walk speed value.
So um, couple of ways you can do this.
Um I, I'm going to use a repeat until false loop here to do this, which um, is not always the best
practice.
Um, in fact, now that I think about it, um.
The humanoids here changed as humanoid.
Have some kind of thing tracking the position.
See?
We can't move it all here.
Move direction?
No, because it would be our only option, really, to do it that way.
Um, we could do it based on the position, so.
But like, every time the place position changes, then we can do this.
But the reason why I want to use the repeat until false here is, um, I want the amount it adds on
to the player's speed to be the same no matter how fast they are.
So if we only do this a maximum of ten times a second.
Um, and that's how fast they are.
It's not.
It will, it will work the same amount.
But if we do something based on saying like, um, when the torso changes, um, it's going to be changing
more or more or faster when, when the player is moving faster.
So, um, it'll kind of be a curve.
So like, you start oh, it back, it'll be more.
It'll be, it'll be, it'll be more curved like the, um, and once you get, once you get really fast,
you'll be able to just progress way too quickly.
Um, which is why I'm wanting to do it this way instead.
So we need to check to see if they are moving, obviously.
And if they are, we're going to set the speed value to equal the current speed plus a certain amount.
Now done a bit of looking into this.
And 0.01 I think is quite a good amount here.
Feel free to try this out and vary this for yourself, but I think that's the best value for this.
And then immediately update the humanoids walk speed as well.
Speed is equal to speed dot value.
So the player is actually getting this new speed value and it's repeat until false.
You need to make sure we put a weight in here and wait for about 0.1 seconds I think.
So if the player is just walking straight it'll check ten times a second.
So they'll be moving.
They'll be increasing by 0.1 a second.
So one in about 10s, which I think is quite a good amount really.
But feel free to change this based on how easy or hard you want.
You want the game to be for the players.
Okay.
And let's then try all of this out.
So if we load in here, we're able to move forward a bit.
And you can see here the speed increasing.
And I'm slowly and slowly becoming a bit faster.
Um and yeah there we go.
So a nice simple script that allows us to make these changes.
And this really is the base fundamental part of our game.
Of course we're going to make other additions.
But really this is a complete base of the game.
When you walk you gain speed.
Cool.
So we're going to stop it there.
So I do want to add a bit more on to this game though.
It would be a little bit boring if it was just that.
Now the main thing for this is the shop, which we're going to spend quite a bit of this game designing
this game on.
This shop is going to contain, um, some items that a player can buy and with a cooldown, of course,
they can activate these items which will get them, which will then get them speed.
So in the next lesson, we're going to start this off by designing the shop guy.
As long as a separate shop not shop, but a separate guy to display the stats.
So this is going to be it's going to display the level and the walk speed just so that maybe for possibility
in the future, if you want to make your if you want to disable the leaderboard.
It's quite a few games don't actually have a leaderboard enabled as it doesn't look the prettiest.
Don't think.
Um, but yeah.
So the next lecture we're going to have a look at a bit of design.